/*
题目: 添加与搜索单词
请你设计一个数据结构，支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。

实现词典类 WordDictionary ：

    WordDictionary() 初始化词典对象
    void addWord(word) 将 word 添加到数据结构中，之后可以对它进行匹配
    bool search(word) 如果数据结构中存在字符串与 word 匹配，则返回 true ；否则，返回  false 。word 中可能包含一些 '.' ，每个 . 都可以表示任何一个字母。

https://leetcode.cn/problems/design-add-and-search-words-data-structure/
 */
class WordDictionary {
    public static class Trie {
        boolean isEnd;
        Trie[] children;
        public Trie() {
            this.isEnd = false;
            children = new Trie[26];
        }
    }
    Trie root = null;

    public WordDictionary() {
        root = new Trie();
    }
    
    public void addWord(String word) {
        int n = word.length();
        Trie head = root;
        for (int i = 0; i < n; i ++) {
            char ch = word.charAt(i);
            int pos = ch - 'a';

            if (head.children[pos] == null)     head.children[pos] = new Trie();
            
            head = head.children[pos];
        }
        head.isEnd = true;
    }
    
    public boolean search(String word) {
        return DFS(word, word.length(), 0, root);
    }

    private boolean DFS(String word, int len, int pos, Trie head) {
        if (pos == len)     return head.isEnd; // 到最后一个字符, 判断

        char ch = word.charAt(pos);
        if (ch == '.') {
            // '.' 表示什么都行, 直接跳过这个字符, 去尝试匹配接下来的 26 个 字母
            for (int k = 0; k < 26; k ++) {
                if (head.children[k] != null && DFS(word, len, pos + 1, head.children[k])) {
                    return true;
                }
            }
        } else {
            int cur = ch - 'a';
            if (head.children[cur] == null)     return false;

            if (DFS(word, len, pos + 1, head.children[cur])) {
                return true;
            }
        } 
        return false;
    }
}

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary obj = new WordDictionary();
 * obj.addWord(word);
 * boolean param_2 = obj.search(word);
 */